package ks.server.controllers.commands.general.table;

import ks.framework.common.Message;
import ks.framework.communicator.Communicator;
import ks.framework.interfaces.IProcessMessage;
import ks.managers.table.Table;
import ks.managers.table.TableManager;
import ks.server.ServerContext;
import ks.server.controllers.requests.LeftRequest;
import ks.server.controllers.requests.ModeratorRequest;
import ks.server.ipc.Listener;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * @author Jared Razee
 * @author Christopher Page
 */
public class LeaveController implements IProcessMessage {
	
	/** Primary agent to whom we can communicate our messages. */
	Communicator com;
	
	public LeaveController (Communicator com) {
		this.com = com;
	}

	public boolean process(Message m) {
		Node leaveNode = m.contents();
		
		NamedNodeMap nnp = leaveNode.getAttributes();
		
		Node tableNode = nnp.getNamedItem("table");
		Node playerNode = nnp.getNamedItem("player");
		
		String clientPlayer = m.getOriginator();
		
		if (tableNode == null) {
			Message n = Listener.nack(m, 4, "tableNode null");
			n.setRecipient(clientPlayer);
			com.distribute(n);
			return false;
		}
		
		int tableNum = Integer.parseInt(tableNode.getNodeValue());
		TableManager tm = ServerContext.getTableManager();
		Table t = tm.getTable(tableNum);
		
		if (playerNode != null) {
			if (!t.getModerator().equals(clientPlayer)) {
				Message n = Listener.nack(m, 4, "Access denied.");
				n.setRecipient(clientPlayer);
				com.distribute(n);
				return false;
			}
			
			String player = playerNode.getNodeValue();
			
			t.removePlayer(player);
			
			Message n = Listener.ack(m, "Kick successful.");  // high severity level
			n.setRecipient(clientPlayer);
			com.distribute(n);
			
			boolean result = new LeftRequest(com).send(tableNum, player, true);
			
			if (modFix(t))
				result = result && new ModeratorRequest(com).send(tableNum, t.getModerator());
			
			return result;
		}
		else {
			t.removePlayer(clientPlayer);
			
			Message n = Listener.ack(m, "Leave table successful.");  // high severity level
			n.setRecipient(clientPlayer);
			com.distribute(n);
			
			boolean result = new LeftRequest(com).send(tableNum, clientPlayer);
			
			if (modFix(t))
				result = result && new ModeratorRequest(com).send(tableNum, t.getModerator());
			
			return result;
		}
	}
	
	private boolean modFix(Table t) {
		if ((t.getModerator() != null && !t.getPlayers().contains(t.getModerator())) && !t.getPlayers().isEmpty()) {
			for (String player : t.getPlayers()) {
				if (player != null)
					t.setModerator(player);
			}
		}
		else if ((t.getModerator() != null && !t.getPlayers().contains(t.getModerator())) && t.getPlayers().isEmpty()) {
			t.setModerator(null);
		}
		else
			return false;
		return true;
	}
}
